{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "e1273450",
   "metadata": {},
   "source": [
    "## Connecting graph-notebook to a Gremlin Server\n",
    "\n",
    "![Gremlin](https://github.com/aws/graph-notebook/blob/main/images/gremlin-notebook.png?raw=true, \"Picture of Gremlin holding a notebook\")\n",
    "\n",
    "\n",
    "See [\"Connecting graph-notebook to a Gremlin Server\"](https://github.com/aws/graph-notebook/tree/main/additional-databases/gremlin-server) for more details.\n",
    "These notes explain how to connect the graph-notebook to a Gremlin server running locally on the same machine. The same steps should also work if you have a remote Gremlin Server. In such cases `localhost` should be replaced with the DNS or IP address of the remote server. It is assumed the [graph-notebook installation](https://github.com/aws/graph-notebook/blob/main/README.md) has been completed and the Jupyter environment is running before following these steps.\n",
    "\n",
    "\n",
    "### Connecting to a local Gremlin Server from Jupyter\n",
    "1. In the Jupyter Notebook disable SSL using `%%graph_notebook_config` and change the host to `localhost`. Keep the other defaults even though they are not used for configuring the Gremlin Server.\n",
    "```\n",
    "%%graph_notebook_config\n",
    "{\n",
    "    \"host\": \"localhost\",\n",
    "    \"port\": 8182,\n",
    "    \"ssl\": false,\n",
    "    \"proxy_port\": 8192,\n",
    "    \"proxy_host\": \"\",\n",
    "    \"auth_mode\": \"\",\n",
    "    \"aws_region\": \"\",\n",
    "    \"load_from_s3_arn\": \"\"\n",
    "}\n",
    "```\n",
    "\n",
    "\n",
    "### Connecting to a local Gremlin Server from Jupyter\n",
    "- If the Gremlin Server you wish to connect to is remote,  replacing `localhost` with the IP address or DNS of the remote server should work. This assumes you have access to that server from your local machine.\n",
    "- If you wish to connect to a Neptune Server from your local machine then you must have a viable Proxy solution to access the Neptune instance inside its VPC. This model can be seen in [this aws-samples post.](https://aws-samples.github.io/aws-dbs-refarch-graph/src/connecting-using-a-load-balancer/)(CDK Construct Pending).\n",
    "\n",
    "#### Remote Gremlin Server\n",
    "```\n",
    "%%graph_notebook_config\n",
    "{\n",
    "    \"host\": \"remote.gremlin.com\",\n",
    "    \"port\": 8182,\n",
    "    \"ssl\": false,\n",
    "    \"proxy_port\": 8192,\n",
    "    \"proxy_host\": \"\",\n",
    "    \"auth_mode\": \"\",\n",
    "    \"aws_region\": \"\",\n",
    "    \"load_from_s3_arn\": \"\"\n",
    "}\n",
    "```\n",
    "\n",
    "#### Proxied Neptune Server\n",
    "```\n",
    "%%graph_notebook_config\n",
    "{\n",
    "    \"host\": \"neptunedatabasecluster.cluster-XXXXXXX.us-east-1.neptune.amazonaws.com\",\n",
    "    \"port\": 8182,\n",
    "    \"ssl\": true,\n",
    "    \"proxy_port\": 8192,\n",
    "    \"proxy_host\": \"nlb.proxy.aws.com\",\n",
    "    \"auth_mode\": \"IAM\",\n",
    "    \"aws_region\": \"us-east-1\",\n",
    "    \"load_from_s3_arn\": \"\"\n",
    "}\n",
    "```\n",
    "- IAM Authed connections through a proxied connection require the request to be signed with the HOST header set to the value of the Neptune endpoint, not the NLB endpoint. This process is handled by default in the [NeptuneUtils Library](https://github.com/awslabs/amazon-neptune-tools/tree/master/neptune-python-utils) published by neptune.\n",
    "- Non-IAM Authed databases will not have to worry about this signing issue, however, it is recommended that there be some type of authentication before the request is allowed to interact with your database.\n",
    "\n",
    "\n",
    "## Example NeptuneUtils Implementation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "989ea92e",
   "metadata": {},
   "outputs": [],
   "source": [
    "from neptune_python_utils.gremlin_utils import GremlinUtils\n",
    "from neptune_python_utils.endpoints import Endpoints\n",
    "\n",
    "endpoints = Endpoints(\n",
    "    neptune_endpoint='demo.cluster-111222333.eu-west-2.neptune.amazonaws.com', \n",
    "    region_name='us-east-1',\n",
    "    proxy_dns='localhost',\n",
    "    proxy_port=8182,\n",
    "    remove_host_header=False)\n",
    "    \n",
    "GremlinUtils.init_statics(globals())\n",
    "    \n",
    "gremlin_utils = GremlinUtils(endpoints)\n",
    "\n",
    "conn = None\n",
    "\n",
    "try:\n",
    "    conn = gremlin_utils.remote_connection(ssl=False)\n",
    "    g = gremlin_utils.traversal_source(connection=conn)\n",
    "    print(g.V().limit(10).valueMap().toList())\n",
    "finally:\n",
    "    if conn:\n",
    "        conn.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "550fcd2d",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
